package liangtWorkSpace.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @ClassName AcpectDemo
 * @Description : 功能说明
 * @Author : LiangT
 * @Date : 2020/4/24 18:22
 */
@Component
@Aspect
public class AcpectDemo {
    private static final Logger logger = LoggerFactory.getLogger(AcpectDemo.class);
    /**
     * 定义一个PointCut使用切点表达式
     * 1）execution(public * *(..))——表示匹配所有public方法
     * 2）execution(* set*(..))——表示所有以“set”开头的方法
     * 3）execution(* com.xyz.service.AccountService.*(..))——表示匹配所有AccountService接口的方法
     * 4）execution(* com.xyz.service.*.*(..))——表示匹配service包下所有的方法
     * 5）execution(* com.xyz.service..*.*(..))——表示匹配service包和它的子包下的方法
     */
    //类切面
    //    @Pointcut("execution(public * liangtWorkSpace.controller.TestController.*(..)))")
    //包切面
    //    @Pointcut("execution(public * liangtWorkSpace.controller.TestController..*(..)))")
    //方法切面
        @Pointcut("execution(public * liangtWorkSpace.controller.TestController.test(..)))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before(JoinPoint point){
        System.out.println("前置拦截:"+Arrays.asList(point.getArgs()));
        logger.info("Before method{} invoke param:{}",point.getSignature().toLongString(),point.getArgs());
    }
    /**
     * @description  在连接点执行之后执行的通知（返回通知和异常通知的异常）
     */
    @After("pointCut()")
    public void doAfterGame(){
        System.out.println("后置拦截");
    }

    @AfterReturning(pointcut = "pointCut()", returning = "retVal")
    public void logMethodInvokeResult(JoinPoint point, Object retVal) {
        System.out.println("返回拦截");
        String str = "连接点为："+point.getSignature().getName()+",参数为："+ Arrays.asList(point.getArgs())+",异常为："+retVal;
        System.out.println(str);
    }

    @AfterThrowing(pointcut = "pointCut()", throwing = "exception")
    public void logMethodInvokeException(JoinPoint point, Exception exception) {
        System.out.println("异常处理");
        logger.info("method {} invoke exception: {}", point.getSignature().toShortString(), exception.getMessage());
    }

    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint){
        try {
            System.out.println("前置缠绕！");
            Object o = joinPoint.proceed();
            System.out.println("后置缠绕");
            return o;
        }catch (Exception e){
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }return null;
    }
}
